# # 查看环境变量
# echo $env:SECURE_CONFIG_MASTER_KEY
import streamlit as st
import os
import hashlib
import logging
from typing import Dict, Any, Optional, List, Tuple
import json
import time

from secure_config_manager.core.keychain import SystemKeychain
from secure_config_manager.core.encryption import EnhancedAES256Encryptor
from secure_config_manager.core.config_manager import SecureConfigManager
from secure_config_manager.utils.storage_adapters import (
    S3StorageAdapter, 
    WebDavStorageAdapter,
    StorageOperations
)
from secure_config_manager.utils.memory_safety import SecureMemory
from secure_config_manager.core.kms_integration import KMSIntegration
from secure_config_manager.webui.kms_integration_ui import render_kms_integration_ui

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# 常量定义
CONFIG_TABS = {
    "首页": "🏠",
    "安全密钥管理": "🔑",
    "配置管理": "⚙️",
    "云端存储": "☁️",
    "KMS集成": "🔐"
}
STORAGE_TYPES = {
    "s3": "S3兼容存储",
    "webdav": "WebDAV服务"
}

# S3兼容服务模板
S3_SERVICE_TEMPLATES = {
    "custom": {
        "name": "自定义配置",
        "endpoint_url": "",
        "region_name": "",
        "description": "手动配置所有参数"
    },
    "minio": {
        "name": "MinIO",
        "endpoint_url": "http://localhost:9000",
        "region_name": "",
        "description": "开源S3兼容对象存储服务"
    },
    "aliyun": {
        "name": "阿里云OSS",
        "endpoint_url": "https://oss-cn-hangzhou.aliyuncs.com",
        "region_name": "cn-hangzhou",
        "description": "阿里云对象存储服务"
    },
    "tencent": {
        "name": "腾讯云COS",
        "endpoint_url": "https://cos.ap-guangzhou.myqcloud.com",
        "region_name": "ap-guangzhou",
        "description": "腾讯云对象存储服务"
    },
    "qiniu": {
        "name": "七牛云Kodo",
        "endpoint_url": "https://s3-cn-east-1.qiniucs.com",
        "region_name": "cn-east-1",
        "description": "七牛云对象存储服务"
    }
}

# WebDAV服务模板
WEBDAV_SERVICE_TEMPLATES = {
    "custom": {
        "name": "自定义WebDAV",
        "webdav_url": "",
        "description": "手动配置WebDAV服务"
    },
    "nextcloud": {
        "name": "Nextcloud",
        "webdav_url": "https://nextcloud.example.com/remote.php/dav/files/username/",
        "description": "Nextcloud WebDAV服务"
    },
    "owncloud": {
        "name": "ownCloud",
        "webdav_url": "https://owncloud.example.com/remote.php/dav/files/username/",
        "description": "ownCloud WebDAV服务"
    },
    "seafile": {
        "name": "Seafile",
        "webdav_url": "https://seafile.example.com/seafdav/",
        "description": "Seafile WebDAV服务"
    },
    "box": {
        "name": "Box",
        "webdav_url": "https://dav.box.com/dav/",
        "description": "Box.com WebDAV服务"
    }
}

def init_session_state():
    """初始化会话状态变量"""
    if 'master_key' not in st.session_state:
        st.session_state.master_key = None
    
    if 'is_initialized' not in st.session_state:
        st.session_state.is_initialized = False
        
    if 'active_section' not in st.session_state:
        st.session_state.active_section = None
        
    if 'active_tab' not in st.session_state:
        st.session_state.active_tab = "首页"
        
    if 'sections' not in st.session_state:
        st.session_state.sections = []
        
    if 'encrypted_data' not in st.session_state:
        st.session_state.encrypted_data = {}
        
    if 'new_key' not in st.session_state:
        st.session_state.new_key = None
    
    if 'system_initialized' not in st.session_state:
        st.session_state.system_initialized = False
    
    if 'system_keychain' not in st.session_state:
        st.session_state.system_keychain = None
        
    if 'config_handler' not in st.session_state:
        st.session_state.config_handler = None
        
    if 'kms_integration' not in st.session_state:  # 新增KMS集成实例
        st.session_state.kms_integration = None
        
    # 密钥轮换相关状态
    if 'show_rotation_confirm' not in st.session_state:
        st.session_state.show_rotation_confirm = False
        
    if 'rotation_in_progress' not in st.session_state:
        st.session_state.rotation_in_progress = False
        
    if 'rotation_completed' not in st.session_state:
        st.session_state.rotation_completed = False
        
    # 密钥清除相关状态
    if 'show_clear_confirm' not in st.session_state:
        st.session_state.show_clear_confirm = False
        
    if 'key_cleared' not in st.session_state:
        st.session_state.key_cleared = False
        
    if 'temp_key' not in st.session_state:
        st.session_state.temp_key = ""
        
    # 密钥查看状态
    if 'show_key' not in st.session_state:
        st.session_state.show_key = False

    # 明文加密相关状态 (新增)
    if 'show_encrypt_plaintext_confirm' not in st.session_state:
        st.session_state.show_encrypt_plaintext_confirm = False
    if 'encrypt_plaintext_in_progress' not in st.session_state:
        st.session_state.encrypt_plaintext_in_progress = False
    if 'encrypt_plaintext_completed' not in st.session_state:
        st.session_state.encrypt_plaintext_completed = False
    if 'encrypt_plaintext_results' not in st.session_state:
         st.session_state.encrypt_plaintext_results = {"success": [], "errors": []}

def show_security_warning(master_key: str):
    """显示密钥安全警告"""
    with st.expander("⚠️ 重要安全提示", expanded=True):
        st.markdown(f"""
        **请立即执行以下操作：**
        1. 将下方密钥添加到系统环境变量
        2. 妥善保存此密钥（建议使用密码管理器）
        3. 不要将密钥提交到版本控制系统

        ```bash
        [System.Environment]::SetEnvironmentVariable("SECURECONFIGMASTERKEY", "{master_key}", "User")
        ```
        """)
        st.code(master_key)

def system_initialization():
    """系统初始化界面组件"""
    st.subheader("🔐 密钥管理系统")

    # 显示初始化状态
    is_initialized = SystemKeychain.is_initialized()
    
    if not is_initialized:
        st.info("系统尚未初始化，正在准备初始化过程...")
        
        try:
            master_key = SystemKeychain.initialize_keychain()
            st.success("系统已自动初始化完成！")
            show_security_warning(master_key)
            st.session_state.initialized = True
            
            # 添加继续操作提示
            st.info("🔄 请刷新页面或点击下方按钮继续使用系统")
            if st.button("✅ 继续使用系统"):
                st.rerun()
                
        except Exception as e:
            logger.error(f"初始化失败: {str(e)}")
            st.error(f"初始化失败: {str(e)}")
            st.error("请检查系统权限并重试")
    else:
        st.success("✅ 系统已初始化")
        # 密钥管理操作
        show_advanced_key_operations()
        
        # 添加功能导航
        st.info("👆 请使用上方的标签页访问系统其他功能")

def show_advanced_key_operations():
    """显示高级密钥操作界面"""
    st.subheader("高级密钥操作")
    
    # 渲染主要密钥管理按钮
    render_key_management_buttons()
    
    # 渲染密钥轮换UI和结果
    render_key_rotation_ui()
    render_rotation_result()
    
    # 渲染密钥清除UI和结果
    render_key_clear_ui()
    render_clear_result()

    # 渲染明文加密UI和结果
    render_encrypt_plaintext_ui()
    render_encrypt_plaintext_result()
    
    # 渲染查看密钥UI
    render_view_key_ui()

def render_key_management_buttons():
    """渲染密钥管理主按钮"""
    # 检查是否有任何操作正在进行中 (添加了明文加密状态)
    any_operation_active = (
        st.session_state.show_rotation_confirm or
        st.session_state.show_clear_confirm or
        st.session_state.rotation_in_progress or
        st.session_state.show_encrypt_plaintext_confirm or
        st.session_state.encrypt_plaintext_in_progress
    )

    # 添加调试模式开关
    show_debug = st.checkbox("显示调试信息", value=False, key="show_file_status_debug")
    
    # 获取文件状态
    has_files, encrypted_files, plaintext_files = check_file_encryption_status()
    
    # 显示调试信息
    if show_debug:
        st.write("### 文件状态调试信息")
        st.write(f"- 是否有文件: {has_files}")
        st.write(f"- 加密文件数量: {len(encrypted_files)}")
        st.write(f"- 明文文件数量: {len(plaintext_files)}")
        
        if encrypted_files:
            with st.expander("加密文件列表", expanded=True):
                for file in encrypted_files:
                    st.write(f"🔒 {file}")
                    
        if plaintext_files:
            with st.expander("明文文件列表", expanded=True):
                for file in plaintext_files:
                    st.write(f"📄 {file}")
        
        # 添加文件内容检查
        if has_files:
            st.write("### 文件内容检查")
            # 创建ConfigManager实例
            manager = SecureConfigManager()
            all_files = manager.list_configs()
            selected_file = st.selectbox("选择要检查的文件", all_files)
            
            if selected_file:
                try:
                    # 读取文件内容
                    config_path = os.path.join(manager.config_dir, f"{selected_file}{manager.CONFIG_EXTENSION}")
                    with open(config_path, 'r', encoding='utf-8') as f:
                        file_content = json.load(f)
                    
                    # 显示文件内容
                    st.json(file_content)
                    
                    # 分析加密状态
                    is_probably_encrypted = False
                    for section_key, section_data in file_content.items():
                        if isinstance(section_data, dict):
                            # 检查顶级键是否包含加密标识
                            if {'ciphertext', 'salt', 'nonce', 'tag'}.issubset(section_data.keys()):
                                is_probably_encrypted = True
                                st.success(f"顶级键 '{section_key}' 包含加密数据")
                                break
                            
                            # 检查子键
                            for sub_key, sub_value in section_data.items():
                                if isinstance(sub_value, dict) and {'ciphertext', 'salt', 'nonce', 'tag'}.issubset(sub_value.keys()):
                                    is_probably_encrypted = True
                                    st.success(f"子键 '{section_key}.{sub_key}' 包含加密数据")
                                    break
                            
                            if is_probably_encrypted:
                                break
                    
                    if not is_probably_encrypted:
                        st.warning("此文件未检测到加密数据")
                        
                except Exception as e:
                    st.error(f"读取文件时出错: {e}")

    # 第一行：密钥轮换和密钥清除按钮
    col1, col2, col3 = st.columns(3)

    with col1:
        # 检查文件是否有加密状态
        rotation_disabled = any_operation_active or not encrypted_files
        
        if not encrypted_files and has_files:
            rotation_help = "密钥轮换需要对加密状态的文件执行，当前没有加密文件"
        else:
            rotation_help = "生成新密钥并重新加密所有数据"
            
        rotation_clicked = st.button(
            "🔄 密钥轮换",
            help=rotation_help,
            use_container_width=True,
            disabled=rotation_disabled
        )
        if rotation_clicked:
            # 初始化状态
            st.session_state.show_rotation_confirm = True
            st.session_state.show_clear_confirm = False
            st.session_state.show_encrypt_plaintext_confirm = False # 重置其他确认
            st.session_state.rotation_in_progress = False
            st.session_state.rotation_completed = False
            st.rerun()

    with col2:
        # 检查文件是否有加密状态
        has_files, encrypted_files, plaintext_files = check_file_encryption_status()
        clear_disabled = any_operation_active or not encrypted_files
        
        if not encrypted_files and has_files:
            clear_help = "密钥清除需要对加密状态的文件执行，当前没有加密文件"
        else:
            clear_help = "解密所有配置文件为明文，并清除主密钥"
            
        clear_key_clicked = st.button(
            "🗑️ 清除密钥(转明文)", # 修改按钮文字和帮助信息
            help=clear_help,
            use_container_width=True,
            disabled=clear_disabled
        )
        if clear_key_clicked:
            # 初始化状态
            st.session_state.show_clear_confirm = True
            st.session_state.show_rotation_confirm = False
            st.session_state.show_encrypt_plaintext_confirm = False # 重置其他确认
            st.rerun()

    # 添加新的 "明文加密" 按钮
    with col3:
        # 检查文件是否有明文状态
        has_files, encrypted_files, plaintext_files = check_file_encryption_status()
        encrypt_disabled = any_operation_active or not plaintext_files
        
        if not plaintext_files and has_files:
            encrypt_help = "明文加密需要对明文状态的文件执行，当前没有明文文件"
        else:
            encrypt_help = "使用当前主密钥加密所有明文配置文件"
            
        encrypt_plaintext_clicked = st.button(
            "🔒 明文加密",
            help=encrypt_help,
            use_container_width=True,
            disabled=encrypt_disabled
        )
        if encrypt_plaintext_clicked:
            # 检查主密钥是否存在
            try:
                master_key = SystemKeychain.get_master_key()
                if not master_key:
                    st.error("❌ 未找到主密钥！请先在系统环境变量中设置 `SECURECONFIGMASTERKEY`。")
                    logger.warning("尝试明文加密但未找到主密钥。")
                else:
                    # 主密钥存在，显示确认对话框
                    st.session_state.show_encrypt_plaintext_confirm = True
                    st.session_state.show_rotation_confirm = False # 重置其他确认
                    st.session_state.show_clear_confirm = False    # 重置其他确认
                    st.session_state.encrypt_plaintext_in_progress = False
                    st.session_state.encrypt_plaintext_completed = False
                    logger.info("明文加密按钮点击，准备显示确认。")
                    st.rerun()
            except Exception as e:
                 st.error(f"检查主密钥时出错: {e}")
                 logger.error(f"检查主密钥时出错: {e}", exc_info=True)


    # 第二行：查看当前密钥按钮（只有在没有显示确认对话框时才显示）
    if not any_operation_active:
        st.markdown("---")
        button_text = "🔍 查看当前密钥"
        if st.button(button_text, help="显示或刷新当前系统密钥", use_container_width=True):
            st.session_state.show_key = not st.session_state.show_key  # 切换显示状态
            st.rerun()

def _render_rotation_confirmation_dialog() -> Optional[bool]:
    """渲染密钥轮换确认对话框，返回用户操作结果."""
    with st.container():
        st.warning("""
        **危险操作警告：**
        - 请确保系统处于维护时段
        - 确认已备份当前密钥
        - 该操作会导致服务短暂不可用
        """)
        
        # 显示加密文件状态信息
        has_files, encrypted_files, plaintext_files = check_file_encryption_status()
        if encrypted_files:
            st.info(f"将对 {len(encrypted_files)} 个加密文件执行密钥轮换")
            with st.expander("查看加密文件列表", expanded=False):
                for filename in encrypted_files:
                    st.write(f"🔒 {filename}")
        
        confirm_checkbox = st.checkbox(
            "我已理解风险并确认操作", 
            key="confirm_rotation_checkbox"
        )
        
        col1, col2 = st.columns([1, 1])
        with col1:
            confirm_button = st.button(
                "✅ 确认执行轮换", 
                key="confirm_rotation_button", 
                disabled=not confirm_checkbox,
                use_container_width=True
            )
        
        with col2:
            cancel_button = st.button(
                "❌ 取消操作", 
                key="cancel_rotation_button",
                use_container_width=True
            )

        if cancel_button:
            return False  # 用户取消
        if confirm_checkbox and confirm_button:
            return True   # 用户确认
    return None # 用户未操作

def _execute_key_rotation_logic():
    """执行密钥轮换的核心逻辑."""
    # 检查文件是否处于加密状态
    has_files, encrypted_files, plaintext_files = check_file_encryption_status()
    if not encrypted_files:
        st.error("❌ 无法执行密钥轮换：未找到加密状态的文件。")
        logger.error("尝试执行密钥轮换但未找到加密文件。")
        reset_rotation_state()
        st.rerun()
        return
        
    with st.spinner("正在生成新密钥并重新加密所有数据..."):
        try:
            current_key = SystemKeychain.get_master_key()
            # 执行密钥轮换
            new_key = SystemKeychain.rotate_key(current_key)
            reencrypt_all_data(current_key, new_key)
            
            # 保存新密钥并更新状态
            st.session_state.new_key = new_key.decode('utf-8') if isinstance(new_key, bytes) else new_key
            st.session_state.rotation_completed = True
            st.session_state.rotation_in_progress = False
            st.session_state.show_rotation_confirm = False  # 关闭确认对话框
            st.rerun()
        except Exception as e:
            st.error(f"密钥轮换过程中发生错误: {str(e)}")
            logger.error(f"密钥轮换错误: {str(e)}", exc_info=True)

def render_key_rotation_ui():
    """渲染密钥轮换确认和执行UI"""
    # 如果不需要显示确认框或者轮换已完成，不显示UI
    if not st.session_state.show_rotation_confirm or st.session_state.rotation_completed:
        return
        
    st.markdown("---")
    st.subheader("🔄 密钥轮换")
    
    # 步骤1：确认对话框
    if not st.session_state.rotation_in_progress:
        user_action = _render_rotation_confirmation_dialog()
        
        if user_action is True: # 用户确认
            st.session_state.rotation_in_progress = True
            st.rerun()
        elif user_action is False: # 用户取消
            reset_rotation_state()
            st.rerun()
            
    # 步骤2：执行轮换
    elif st.session_state.rotation_in_progress:
        try:
            # 显示当前密钥指纹
            current_key = SystemKeychain.get_master_key()
            key_fingerprint = hashlib.sha256(current_key).hexdigest()[:16]
            st.text("当前密钥指纹")
            st.code(f"{key_fingerprint}")
            
            # 执行按钮和取消按钮
            col1, col2 = st.columns([1, 3])
            with col1:
                if st.button("❌ 取消", key="cancel_rotation_final", use_container_width=True):
                    reset_rotation_state()
                    st.rerun()
            
            with col2:
                execute_button = st.button(
                    "🔄 立即执行密钥轮换", 
                    key="execute_rotation", 
                    use_container_width=True
                )
                if execute_button:
                    _execute_key_rotation_logic() # 调用执行逻辑
                    
        except Exception as e:
            st.error(f"无法获取当前密钥: {str(e)}")
            logger.error(f"密钥获取失败: {str(e)}")
            reset_rotation_state()

def render_rotation_result():
    """显示密钥轮换结果"""
    if not st.session_state.rotation_completed or not st.session_state.new_key:
        return
        
    st.markdown("---")
    st.subheader("🎉 密钥轮换完成")
    st.success("系统数据已使用新密钥重新加密！")
    
    # 显示新密钥信息
    with st.expander("新密钥信息", expanded=True):
        st.info("请将新密钥保存到安全位置并设置为环境变量")
        
        # 默认显示部分隐藏的密钥
        new_key = st.session_state.new_key
        masked_key = f"{new_key[:5]}****{new_key[-5:]}"
        
        show_full = st.checkbox("显示完整密钥", key="show_full_new_key")
        if show_full:
            st.code(new_key)
        else:
            st.code(f"部分显示: {masked_key}")
            
        st.warning("旧密钥将不再有效，请确保更新所有使用该密钥的系统")
        
        copy_hint = """
        将新密钥设置为环境变量:
        ```
        [System.Environment]::SetEnvironmentVariable("SECURECONFIGMASTERKEY", "{}", "User")
        ```
        """.format(new_key)
        st.markdown(copy_hint)
    
    # 完成按钮
    if st.button("✅ 完成", key="complete_rotation", use_container_width=True):
        reset_rotation_state()
        st.balloons()
        st.rerun()

def _render_clear_confirmation_dialog() -> Optional[bool]:
    """渲染密钥清除确认对话框，返回用户操作结果."""
    with st.container():
        st.warning("⚠️ 警告：清除用户密钥后，系统将使用临时密钥运行")
        
        # 显示加密文件状态信息
        has_files, encrypted_files, plaintext_files = check_file_encryption_status()
        if encrypted_files:
            st.info(f"将对 {len(encrypted_files)} 个加密文件执行解密操作，转换为明文")
            with st.expander("查看加密文件列表", expanded=False):
                for filename in encrypted_files:
                    st.write(f"🔒 {filename}")
        
        confirm_checkbox = st.checkbox(
            "我已了解风险并确认清除", 
            key="confirm_clear_checkbox"
        )
        
        col1, col2 = st.columns([1, 1])
        with col1:
            confirm_button = st.button(
                "✅ 确认清除", 
                key="confirm_clear_button", 
                disabled=not confirm_checkbox,
                use_container_width=True
            )
        
        with col2:
            cancel_button = st.button(
                "❌ 取消操作", 
                key="cancel_clear_button",
                use_container_width=True
            )
            
        if cancel_button:
            return False # 用户取消
        if confirm_checkbox and confirm_button:
            return True  # 用户确认
    return None # 用户未操作

def _execute_key_clear_logic():
    """执行密钥清除的核心逻辑 (更新为解密文件并移除密钥)。"""
    # 检查文件是否处于加密状态
    has_files, encrypted_files, plaintext_files = check_file_encryption_status()
    if not encrypted_files:
        st.error("❌ 无法执行密钥清除：未找到加密状态的文件。")
        logger.error("尝试执行密钥清除但未找到加密文件。")
        reset_clear_state()
        st.rerun()
        return
        
    try:
        # 1. 获取当前主密钥 (必须在清除前获取)
        current_key = SystemKeychain.get_master_key()
        if not current_key:
            st.error("无法获取当前主密钥，无法执行解密操作。")
            reset_clear_state() # 重置状态
            st.rerun()
            return

        # 创建加密器用于解密
        encryptor = EnhancedAES256Encryptor(current_key)
        manager = SecureConfigManager() # 获取配置管理器实例
        config_files = manager.list_configs()

        st.info(f"准备解密 {len(config_files)} 个配置文件...")
        progress = st.progress(0)
        progress_text = st.empty()
        error_files = []
        success_files = []

        # 2. 遍历并解密所有文件
        for idx, filename in enumerate(config_files):
            progress_value = (idx + 1) / len(config_files)
            progress.progress(progress_value)
            progress_text.text(f"正在解密: {filename}{manager.CONFIG_EXTENSION}")
            try:
                decrypted_data = manager.get_decrypted_file_content(filename, encryptor)
                if decrypted_data is not None:
                    # 使用标准库保存明文 JSON
                    # !!! 假设 manager.config_dir 是可访问的配置目录路径 !!!
                    config_path = os.path.join(manager.config_dir, f"{filename}{manager.CONFIG_EXTENSION}")
                    try:
                        with open(config_path, 'w', encoding='utf-8') as f:
                            json.dump(decrypted_data, f, ensure_ascii=False, indent=4)
                        success_files.append(filename)
                        logger.info(f"文件 '{filename}' 已成功解密并保存为明文到 {config_path}。")
                    except IOError as io_err:
                        logger.error(f"无法写入明文文件 '{config_path}': {io_err}", exc_info=True)
                        error_files.append(filename)
                        st.error(f"无法写入明文文件 {filename}: {io_err}")
                    except Exception as save_err: # Catch other potential json errors
                        logger.error(f"保存明文JSON到 '{config_path}' 时出错: {save_err}", exc_info=True)
                        error_files.append(filename)
                        st.error(f"保存明文文件 {filename} 时出错: {save_err}")
                else:
                     # 文件可能是空的或无法解密（虽然理论上应该可以）
                     logger.warning(f"无法解密文件 '{filename}' 或文件为空，跳过。")
                     # 如果需要，可以当作错误处理
                     # error_files.append(filename)
            except Exception as e:
                logger.error(f"解密文件 '{filename}' 时出错: {str(e)}", exc_info=True)
                error_files.append(filename)
                st.error(f"处理文件 {filename} 出错: {e}") # 显示错误

        progress.empty() # 清除进度条
        progress_text.empty()

        if error_files:
            st.error(f"部分文件解密失败: {', '.join(error_files)}. 请检查日志。")
            # 决定是否继续清除密钥，这里选择继续但提示用户
            st.warning("尽管部分文件解密失败，仍将继续清除密钥。")

        # 3. 清除主密钥 (环境变量等)
        success, _ = SystemKeychain.clear_user_key() # 不再需要临时密钥

        if success:
            st.session_state.key_cleared = True # 标记操作完成
            st.session_state.show_clear_confirm = False # 关闭确认对话框
            # st.session_state.temp_key = "" # 确保临时密钥状态被清除
            if 'temp_key' in st.session_state:
                del st.session_state['temp_key']
            logger.info("主密钥已成功清除。")
            st.rerun() # 重新运行以显示结果
        else:
            st.error("❌ 密钥清除失败，但文件可能已被解密为明文。请手动检查环境变量。")
            # 即使密钥清除失败，也可能需要更新UI状态或重置
            reset_clear_state()
            st.rerun()

    except Exception as e:
        st.error(f"密钥清除过程中发生严重错误: {str(e)}")
        logger.error(f"密钥清除操作错误: {str(e)}", exc_info=True)
        reset_clear_state() # 发生错误时重置状态
        st.rerun()

def render_key_clear_ui():
    """渲染密钥清除确认和执行UI"""
    if not st.session_state.show_clear_confirm:
        return
        
    st.markdown("---")
    st.subheader("🗑️ 密钥清除确认")
    
    user_action = _render_clear_confirmation_dialog()
    
    if user_action is True: # 用户确认
        _execute_key_clear_logic()
    elif user_action is False: # 用户取消
        reset_clear_state()
        st.rerun()

def render_clear_result():
    """显示密钥清除结果 (更新为明文状态)"""
    if not st.session_state.get('key_cleared', False): # 检查 key_cleared 状态
        return

    st.markdown("---")
    st.subheader("✅ 密钥已清除，文件已转为明文")
    st.success("所有配置文件已被解密为明文格式，并且主密钥已从系统中移除。")
    st.warning("⚠️ 当前所有配置文件均为 **明文** 存储，请尽快使用新的主密钥进行加密（功能待实现）。")
    st.info("在重新加密之前，请不要在明文文件中存储高度敏感的信息。")

    # 移除显示临时密钥的部分
    # with st.expander("临时密钥详情", expanded=True): ...

    # 完成按钮
    if st.button("✅ 我已知晓", key="complete_clear", use_container_width=True):
        reset_clear_state() # 重置状态
        st.rerun()

def _render_encrypt_plaintext_confirmation_dialog() -> Optional[bool]:
    """渲染明文加密确认对话框，返回用户操作结果."""
    with st.container():
        st.warning("""
        **确认操作：**
        - 此操作将使用当前主密钥加密所有明文配置文件
        - 加密后只能通过密钥访问文件内容
        - 请确保系统环境变量中已设置有效的主密钥
        """)
        
        # 显示明文文件状态信息
        has_files, encrypted_files, plaintext_files = check_file_encryption_status()
        if plaintext_files:
            st.info(f"将对 {len(plaintext_files)} 个明文文件执行加密操作")
            with st.expander("查看明文文件列表", expanded=False):
                for filename in plaintext_files:
                    st.write(f"📄 {filename}")
        
        confirm_checkbox = st.checkbox(
            "我已准备好主密钥并确认加密操作", 
            key="confirm_encrypt_plaintext_checkbox"
        )
        
        col1, col2 = st.columns([1, 1])
        with col1:
            confirm_button = st.button(
                "✅ 确认加密", 
                key="confirm_encrypt_plaintext_button", 
                disabled=not confirm_checkbox,
                use_container_width=True
            )
        
        with col2:
            cancel_button = st.button(
                "❌ 取消操作", 
                key="cancel_encrypt_plaintext_button",
                use_container_width=True
            )

        if cancel_button:
            return False  # 用户取消
        if confirm_checkbox and confirm_button:
            return True   # 用户确认
    return None # 用户未操作

def _execute_encrypt_plaintext_logic():
    """执行明文加密的核心逻辑."""
    # 检查文件是否处于明文状态
    has_files, encrypted_files, plaintext_files = check_file_encryption_status()
    if not plaintext_files:
        st.error("❌ 无法执行明文加密：未找到明文状态的文件。")
        logger.error("尝试执行明文加密但未找到明文文件。")
        reset_encrypt_plaintext_state()
        st.rerun()
        return
        
    try:
        # 1. 获取当前主密钥
        master_key = SystemKeychain.get_master_key()
        if not master_key:
            st.error("❌ 无法获取主密钥！请先在系统环境变量中设置 `SECURECONFIGMASTERKEY`。")
            logger.error("执行明文加密时未找到主密钥。")
            return
            
        # 创建加密器
        encryptor = EnhancedAES256Encryptor(master_key)
        manager = SecureConfigManager()
        
        # 获取所有配置文件（明文JSON文件）
        config_files = manager.list_configs()
        
        if not config_files:
            st.warning("未找到任何配置文件。")
            return
            
        # 显示进度条
        progress = st.progress(0)
        progress_text = st.empty()
        progress_text.text(f"正在加密配置文件...")
        
        # 跟踪处理结果
        success_files = []
        error_files = []
        
        # 处理每个文件
        for idx, filename in enumerate(config_files):
            progress_value = idx / len(config_files)
            progress.progress(progress_value)
            progress_text.text(f"正在处理: {filename}")
            
            try:
                # 读取明文JSON文件
                config_path = os.path.join(manager.config_dir, f"{filename}{manager.CONFIG_EXTENSION}")
                
                try:
                    with open(config_path, 'r', encoding='utf-8') as f:
                        plaintext_data = json.load(f)
                except FileNotFoundError:
                    logger.warning(f"文件 '{config_path}' 不存在，跳过。")
                    continue
                except json.JSONDecodeError as json_err:
                    logger.error(f"文件 '{filename}' 包含无效的JSON: {json_err}")
                    error_files.append(filename)
                    st.error(f"文件 {filename} 包含无效的JSON: {json_err}")
                    continue
                
                # 检查文件是否已加密
                is_already_encrypted = False
                for section_key, section_data in plaintext_data.items():
                    if isinstance(section_data, dict) and 'ciphertext' in section_data and 'salt' in section_data:
                        is_already_encrypted = True
                        break
                
                if is_already_encrypted:
                    logger.info(f"文件 '{filename}' 似乎已经加密，跳过。")
                    continue
                
                # 加密数据
                try:
                    manager.encrypt_and_save_content(filename, plaintext_data, encryptor)
                    success_files.append(filename)
                    logger.info(f"文件 '{filename}' 已成功加密。")
                except Exception as e:
                    error_message = f"加密文件 {filename} 时出错: {str(e)}"
                    logger.error(error_message)
                    st.error(error_message)
                    error_files.append(filename)
                
            except Exception as e:
                error_message = f"处理文件 {filename} 时出错: {str(e)}"
                logger.error(error_message)
                st.error(error_message)
                error_files.append(filename)
        
        # 完成进度条
        progress.progress(1.0)
        progress.empty()
        progress_text.empty()
        
        # 保存结果
        st.session_state.encrypt_plaintext_results = {
            "success": success_files,
            "errors": error_files
        }
        
        # 更新状态
        st.session_state.encrypt_plaintext_completed = True
        st.session_state.encrypt_plaintext_in_progress = False
        st.session_state.show_encrypt_plaintext_confirm = False  # 关闭确认对话框
        st.rerun()
        
    except Exception as e:
        logger.error(f"明文加密操作失败: {str(e)}", exc_info=True)
        st.error(f"明文加密过程中发生错误: {str(e)}")
        # 重置状态
        reset_encrypt_plaintext_state()

def render_encrypt_plaintext_ui():
    """渲染明文加密确认和执行UI"""
    # 如果不需要显示确认框或者加密已完成，不显示UI
    if not st.session_state.show_encrypt_plaintext_confirm or st.session_state.encrypt_plaintext_completed:
        return
        
    st.markdown("---")
    st.subheader("🔒 明文加密确认")
    
    if not st.session_state.encrypt_plaintext_in_progress:
        user_action = _render_encrypt_plaintext_confirmation_dialog()
        
        if user_action is True: # 用户确认
            st.session_state.encrypt_plaintext_in_progress = True
            _execute_encrypt_plaintext_logic()
        elif user_action is False: # 用户取消
            reset_encrypt_plaintext_state()
            st.rerun()

def render_encrypt_plaintext_result():
    """显示明文加密结果"""
    if not st.session_state.encrypt_plaintext_completed:
        return
        
    st.markdown("---")
    st.subheader("🎉 明文加密完成")
    
    results = st.session_state.encrypt_plaintext_results
    success_files = results.get("success", [])
    error_files = results.get("errors", [])
    
    if success_files:
        st.success(f"成功加密 {len(success_files)} 个配置文件！")
        with st.expander("查看成功加密的文件", expanded=False):
            for filename in success_files:
                st.write(f"✅ {filename}")
    
    if error_files:
        st.error(f"有 {len(error_files)} 个文件加密失败。")
        with st.expander("查看加密失败的文件", expanded=True):
            for filename in error_files:
                st.write(f"❌ {filename}")
        
        st.warning("请检查日志以获取详细错误信息。")
    
    # 添加说明
    st.info("所有配置文件已成功加密，现在只能通过系统密钥访问。")
    
    # 完成按钮
    if st.button("✅ 完成", key="complete_encrypt_plaintext", use_container_width=True):
        reset_encrypt_plaintext_state()
        st.rerun()

def render_view_key_ui():
    """渲染查看当前密钥的UI"""
    if not st.session_state.show_key:
        return
        
    try:
        key = SystemKeychain.get_key_from_environment()
        if key:
            st.markdown("#### 当前系统密钥")
            
            # 添加显示完整密钥的选项
            show_full = st.checkbox("显示完整密钥", key="show_full_key_checkbox")
            
            # 显示密钥与隐藏按钮
            col1, col2 = st.columns([4, 1])
            with col1:
                if show_full:
                    # 显示完整密钥
                    st.code(key, language="")
                else:
                    # 显示部分遮蔽的密钥
                    masked_key = f"{key[:5]}****{key[-5:]}"
                    st.code(f"部分显示: {masked_key}", language="")
            
            with col2:
                if st.button("❌ 隐藏", help="隐藏密钥信息", key="hide_key_button"):
                    st.session_state.show_key = False
                    st.rerun()
            
            # 显示密钥操作提示
            if show_full:
                with st.expander("密钥安全提示", expanded=True):
                    st.info("👆 您可以从上方文本中选择并复制密钥")
                    st.warning("请妥善保存密钥，不要将密钥泄露给未授权人员")
                    
                    copy_hint = """
                    将密钥设置为环境变量:
                    ```
                    [System.Environment]::SetEnvironmentVariable("SECURECONFIGMASTERKEY", "{}", "User")
                    ```
                    """.format(key)
                    st.markdown(copy_hint)
        else:
            st.error(f"未找到主密钥，请确保环境变量 {SystemKeychain.ENV_VAR_NAME} 已正确设置")
    except Exception as e:
        logger.error(f"无法获取密钥: {str(e)}")
        st.error(f"无法获取密钥: {str(e)}")

def reset_rotation_state():
    """重置密钥轮换相关状态"""
    st.session_state.show_rotation_confirm = False
    st.session_state.rotation_in_progress = False
    st.session_state.rotation_completed = False
    st.session_state.new_key = None

def reset_clear_state():
    """重置密钥清除相关状态"""
    st.session_state.show_clear_confirm = False
    st.session_state.key_cleared = False
    st.session_state.temp_key = ""

def reset_encrypt_plaintext_state():
    """重置明文加密相关状态"""
    st.session_state.show_encrypt_plaintext_confirm = False
    st.session_state.encrypt_plaintext_in_progress = False
    st.session_state.encrypt_plaintext_completed = False
    st.session_state.encrypt_plaintext_results = {"success": [], "errors": []}

def reencrypt_all_data(old_key: bytes, new_key: bytes):
    """
    使用新密钥重新加密所有配置文件数据
    
    Args:
        old_key: 旧主密钥
        new_key: 新主密钥
    
    Returns:
        bool: 所有文件重新加密是否成功
    """
    try:
        # 创建新旧加密器
        old_encryptor = EnhancedAES256Encryptor(old_key)
        new_encryptor = EnhancedAES256Encryptor(new_key)
        
        # 使用配置管理器访问文件系统
        manager = SecureConfigManager()
        
        # 获取所有配置文件
        config_files = manager.list_configs()
        
        if not config_files:
            return True  # 没有文件不视为错误状态
            
        # 显示进度条
        progress = st.progress(0)
        progress_text = st.empty()
        progress_text.text(f"正在重新加密配置文件...")
        
        # 跟踪处理结果
        success_files = []
        error_files = []
        
        # 处理每个文件
        for idx, filename in enumerate(config_files):
            progress_value = idx / len(config_files)
            progress.progress(progress_value)
            progress_text.text(f"正在处理: {filename}")
            
            try:
                # get_config_data加载包含加密值的JSON结构
                encrypted_data = manager.get_config_data(filename)
                if not encrypted_data:
                    continue  # 跳过此文件
                
                # 使用旧密钥解密
                decrypted_data = manager.get_decrypted_file_content(filename, old_encryptor)
                if not decrypted_data:
                    raise ValueError(f"无法解密文件: {filename}")
                
                # 用新密钥重新加密
                reencrypted_data_map = {}
                
                # 处理每个顶级部分
                for section_key, section_data in decrypted_data.items():
                    if isinstance(section_data, dict):
                        # 递归处理嵌套的字典
                        reencrypted_section = {}
                        for sub_key, sub_value in section_data.items():
                            try:
                                # 假设值是从encrypt_and_save_content加密的base64编码字符串
                                value_bytes = str(sub_value).encode('utf-8')
                                encrypted_value_dict = new_encryptor.encrypt(value_bytes)
                                reencrypted_section[sub_key] = encrypted_value_dict
                            except Exception as e:
                                logger.error(f"重新加密子键失败 '{sub_key}': {str(e)}")
                                reencrypted_section[sub_key] = sub_value  # 出错时保留原始值
                                
                        reencrypted_data_map[section_key] = reencrypted_section
                    elif isinstance(section_data, str):  # 处理顶级加密字符串
                        try:
                            value_bytes = section_data.encode('utf-8')
                            encrypted_value_dict = new_encryptor.encrypt(value_bytes)
                            reencrypted_data_map[section_key] = encrypted_value_dict
                        except Exception as e:
                            logger.error(f"重新加密顶级键失败 '{section_key}': {str(e)}")
                            reencrypted_data_map[section_key] = section_data  # 保留原始值
                    else:
                        # 保持非字典、非字符串值不变（应该不加密）
                        reencrypted_data_map[section_key] = section_data
                
                # 保存重新加密的数据
                manager.save_config_data(filename, reencrypted_data_map)
                success_files.append(filename)
                
            except Exception as e:
                error_message = f"处理文件 {filename} 时出错: {str(e)}"
                logger.error(error_message)
                st.error(error_message)  # 立即显示文件错误
                error_files.append(filename)
            
        # 完成进度条
        progress.progress(1.0)
        progress.empty()  # 清除进度条
        
        # 汇总结果
        success_count = len(success_files)
        error_count = len(error_files)
        
        # 决定部分失败是可接受的还是应该终止该过程
        # 现在，我们继续但报告错误。返回False表示有问题。
        if error_count > 0:
            return False
        
        return True
        
    except Exception as e:
        logger.error(f"重新加密操作失败: {str(e)}")
        st.error(f"重新加密过程中发生错误: {str(e)}")
        return False

def add_new_section(manager: SecureConfigManager):
    """添加新的配置板块"""
    new_section = st.text_input("输入新板块名称", key="new_section_name")
    if st.button("创建新板块"):
        if not new_section:
            st.warning("请输入有效的板块名称")
            return
            
        if new_section in manager.config:
            st.warning("该板块已存在！")
            return
            
        try:
            manager.add_section(new_section, {})
            st.success(f"板块 '{new_section}' 创建成功！")
            st.rerun()  # 刷新板块列表
        except Exception as e:
            logger.error(f"创建板块失败: {str(e)}")
            st.error(f"创建板块失败: {str(e)}")

def get_encryptor() -> Optional[EnhancedAES256Encryptor]:
    """获取当前的加密器实例"""
    try:
        master_key = SystemKeychain.get_master_key()
        if not master_key:
            # Don't show error here directly, let calling function handle None
            logger.warning("无法获取主密钥以创建加密器。")
            return None
        return EnhancedAES256Encryptor(master_key)
    except Exception as e:
        # Log error but don't show Streamlit error directly here
        logger.error(f"获取加密器失败: {e}", exc_info=True)
        return None

def check_file_encryption_status():
    """
    检查配置文件的加密状态
    
    Returns:
        Tuple[bool, List[str], List[str]]: 是否有文件, 加密文件列表, 明文文件列表
    """
    manager = SecureConfigManager()
    config_files = manager.list_configs()
    
    if not config_files:
        return False, [], []
        
    encrypted_files = []
    plaintext_files = []
    
    for filename in config_files:
        try:
            # 读取文件内容
            config_path = os.path.join(manager.config_dir, f"{filename}{manager.CONFIG_EXTENSION}")
            with open(config_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
            
            # 更精确地检查是否是加密文件
            is_encrypted = False
            
            # 首先检查整个数据结构
            if isinstance(data, dict):
                # 方法1: 检查任何顶级键是否包含加密数据
                for section_key, section_data in data.items():
                    # 检查顶级键的值
                    if isinstance(section_data, dict):
                        # 如果值是字典，检查是否包含加密数据
                        if {'ciphertext', 'salt', 'nonce', 'tag'}.issubset(section_data.keys()):
                            is_encrypted = True
                            break
                            
                        # 检查顶级键下的所有子键
                        for sub_key, sub_value in section_data.items():
                            if isinstance(sub_value, dict) and {'ciphertext', 'salt', 'nonce', 'tag'}.issubset(sub_value.keys()):
                                is_encrypted = True
                                break
                        
                        if is_encrypted:
                            break
            
            # 记录文件分类结果
            if is_encrypted:
                encrypted_files.append(filename)
                logger.debug(f"文件 '{filename}' 被识别为加密文件")
            else:
                plaintext_files.append(filename)
                logger.debug(f"文件 '{filename}' 被识别为明文文件")
                
        except Exception as e:
            logger.error(f"检查文件 '{filename}' 加密状态时出错: {e}")
            # 如果无法确定状态，假设为明文
            plaintext_files.append(filename)
            logger.debug(f"文件 '{filename}' 因错误被默认识别为明文文件")
    
    # 记录整体检测结果
    logger.info(f"文件状态检测结果: 共 {len(config_files)} 个文件, 其中加密文件 {len(encrypted_files)} 个, 明文文件 {len(plaintext_files)} 个")
    return len(config_files) > 0, encrypted_files, plaintext_files

# --- Start: File Content Management Functions ---

def add_new_top_level_key(manager: SecureConfigManager, filename: str, current_data: Dict[str, Any], encryptor: EnhancedAES256Encryptor):
    """用于向当前文件数据添加新的顶级键（板块）的UI界面。"""
    
    # 使用容器将整个添加区域分组
    with st.container():
        st.markdown("##### 添加顶级键")
        st.caption("创建一个新的顶级分类，用于组织相关配置")
        
        # 使用一致的列布局
        col1, col2 = st.columns([3, 1])
        
        with col1:
            # 移除固定高度，让其自动调整
            new_key_name = st.text_input(
                label="输入新顶级键名", 
                key=f"new_top_key_input_{filename}",
                placeholder="输入新顶级键名称...",
                label_visibility="collapsed" # 隐藏标签以减少垂直空间
            )
            
        with col2:
            # 移除手动添加的上边距
            # st.markdown("<div style='margin-top: 10px;'></div>", unsafe_allow_html=True)
            
            # 使用更醒目的按钮样式
            if st.button(
                "➕ 创建顶级键", 
                key=f"add_top_key_btn_{filename}", 
                use_container_width=True,
                type="primary"
            ):
                if not new_key_name:
                    st.warning("请输入有效的键名")
                    return # 如果键名为空则停止处理

                if new_key_name in current_data:
                    st.warning("该键名已存在！")
                    return # 如果键已存在则停止处理

                try:
                    current_data[new_key_name] = {} # 初始化为空字典
                    manager.encrypt_and_save_content(filename, current_data, encryptor)
                    st.success(f"顶级键 '{new_key_name}' 创建成功！")
                    # 成功后通过重新运行或显式管理状态来清除输入字段
                    st.rerun()
                except Exception as e:
                    logger.error(f"创建顶级键 '{new_key_name}' 失败: {str(e)}", exc_info=True)
                    st.error(f"创建顶级键失败: {str(e)}")
        
        # 添加分隔线使各部分更清晰
        st.markdown("---")

def add_key_value_pair_to_section(manager: SecureConfigManager, filename: str, current_data: Dict[str, Any], section_key: str, encryptor: EnhancedAES256Encryptor):
    """用于在特定顶级键（板块）下添加键值对的UI界面。"""
    # 在显示添加输入框之前确保目标部分是字典
    if not isinstance(current_data.get(section_key), dict):
        st.caption(f"(顶级键 '{section_key}' 不是字典结构，无法添加子键)")
        return

    st.markdown(f"###### 在 '{section_key}' 下添加键值对") # 使用较小的标题
    
    # 使用与显示子键相同的列宽比例 [2, 3, 1]
    col1, col2, col3 = st.columns([2, 3, 1])
    
    with col1:
        # 使用text_area而不是text_input，保持与显示的子键一致的高度
        new_subkey_key = f"new_subkey_input_{filename}_{section_key}"
        new_subkey = st.text_area(
            "输入子键名", 
            key=new_subkey_key, 
            label_visibility="collapsed", 
            placeholder="子键名",
            height=30 # 将高度从40改为30
        )
        
    with col2:
        new_value_key = f"new_value_input_{filename}_{section_key}"
        new_value = st.text_area(
            "输入对应值", 
            key=new_value_key, 
            label_visibility="collapsed", 
            placeholder="对应值",
            height=30 # 将高度从40改为30
        )
        
    with col3:
        # 添加一个上边距，使按钮垂直居中对齐
        st.markdown("<div style='margin-top: 0px;'></div>", unsafe_allow_html=True) # 将上边距从10px改为0px
        if st.button("➕ 添加", key=f"add_pair_btn_{filename}_{section_key}", use_container_width=True):
             # 由于Streamlit处理按钮点击时的状态，直接检索值
             if not new_subkey:
                st.warning("请输入子键名")
                return # 如果输入缺失则停止
                
             if not new_value:
                st.warning("请输入子键值")
                return # 如果输入缺失则停止

             section_dict = current_data[section_key] # 由于前面的检查，假设它是字典
             if new_subkey in section_dict:
                st.warning(f"子键 '{new_subkey}' 已存在于 '{section_key}' 中，将被覆盖！")
                # 允许覆盖或添加确认步骤（如需要）

             try:
                section_dict[new_subkey] = new_value # 直接修改字典
                manager.encrypt_and_save_content(filename, current_data, encryptor) # 加密并保存整个文件
                st.success(f"成功添加 '{new_subkey}' 到 '{section_key}'")
                # 清除输入可能需要更复杂的状态管理或依赖于重新运行
                st.rerun()
             except Exception as e:
                logger.error(f"添加键值对到 '{section_key}' 失败: {str(e)}", exc_info=True)
                st.error(f"添加键值对失败: {str(e)}")

def display_and_edit_file_content(manager: SecureConfigManager, filename: str, decrypted_data: Dict[str, Any], encryptor: EnhancedAES256Encryptor):
    """显示并提供解密文件内容的编辑控件。"""
    st.markdown("#### 文件内容 (键值对)")

    if not decrypted_data:
        st.caption("该文件当前没有内容。请在上方添加顶级键。")
        return

    # --- 遍历顶级键（板块） ---
    top_keys_to_delete = []
    # 遍历键的副本，以允许在迭代期间从原始字典中删除
    for section_key in list(decrypted_data.keys()):
        section_value = decrypted_data[section_key]

        # 在扩展器标签中使用section_key确保唯一性
        with st.expander(f"🔑 **{section_key}**", expanded=True):

            # --- 添加子键UI（仅当板块是字典时） ---
            if isinstance(section_value, dict):
                 add_key_value_pair_to_section(manager, filename, decrypted_data, section_key, encryptor)
                 st.markdown("---") # 添加UI和现有键之间的分隔符

                 # --- 显示子键 ---
                 if not section_value:
                    st.caption("此顶级键下暂无子键值对。")
                 else:
                    subkeys_to_delete = []
                    # 遍历子键的副本以便安全删除
                    for sub_key in list(section_value.keys()):
                        # 修正：在循环内从可能修改的字典中获取sub_value
                        sub_value = section_value.get(sub_key, "Error: Key not found") # 安全获取值
                        sub_value_display = str(sub_value) # 将值转换为字符串显示

                        # 使用与添加子键相同的列宽和样式
                        sub_cols = st.columns([2, 3, 1])
                        
                        with sub_cols[0]:
                            # 保持一致的高度和样式
                            st.text_area(
                                label=f"subkey_display_{filename}_{section_key}_{sub_key}", 
                                value=sub_key, 
                                disabled=True, 
                                height=18,
                                key=f"sub_key_display_{filename}_{section_key}_{sub_key}", 
                                label_visibility="collapsed"
                            )
                            
                        with sub_cols[1]:
                            # 对于可能较长的值使用一致的高度
                            st.text_area(
                                label=f"val_{filename}_{section_key}_{sub_key}", 
                                value=sub_value_display, 
                                disabled=True, 
                                height=18, 
                                label_visibility="collapsed"
                            )
                            
                        with sub_cols[2]:
                            # 添加上边距以对齐删除按钮
                            st.markdown("<div style='margin-top: 0px;'></div>", unsafe_allow_html=True) # 将上边距从10px改为0px
                            delete_subkey_btn_key = f"del_subkey_btn_{filename}_{section_key}_{sub_key}"
                            # 使用更醒目的按钮样式
                            if st.button(
                                "🗑️", 
                                key=delete_subkey_btn_key, 
                                help=f"删除子键 '{sub_key}'",
                                use_container_width=True
                            ):
                                subkeys_to_delete.append(sub_key)

                    # --- 处理子键删除 ---
                    if subkeys_to_delete:
                        modified = False
                        section_dict = decrypted_data[section_key] # 由于外部检查应该是安全的
                        for sub_key in subkeys_to_delete:
                            if sub_key in section_dict:
                                del section_dict[sub_key]
                                modified = True
                                logger.info(f"标记删除子键 '{sub_key}' 从 '{section_key}' 在文件 '{filename}'")
                        if modified:
                            try:
                                manager.encrypt_and_save_content(filename, decrypted_data, encryptor)
                                st.success(f"成功从 '{section_key}' 删除子键 '{', '.join(subkeys_to_delete)}'。")
                                st.rerun()
                            except Exception as e:
                                logger.error(f"删除子键后保存文件 '{filename}' 失败: {e}", exc_info=True)
                                st.error(f"删除子键失败: {str(e)}")
            else:
                # 如果板块值不是字典，直接显示它
                st.markdown("**值:**")
                # 为保持一致性使用text_area，设置为禁用
                st.text_area(f"val_{filename}_{section_key}", value=str(section_value), disabled=True, height=35, label_visibility="collapsed")
                st.caption("(此顶级键的值不是字典，无法添加子键)")

            # --- 板块操作（删除板块） ---
            st.markdown("---") # 删除按钮前的分隔符
            delete_section_btn_key = f"del_section_btn_{filename}_{section_key}"
            confirm_state_key = f"confirm_delete_section_{filename}_{section_key}"

            # 如果点击了删除按钮，显示确认控件
            if st.session_state.get(confirm_state_key):
                logger.info(f"显示删除确认对话框: 文件={filename}, 键={section_key}")
                st.warning(f"确认删除顶级键 '{section_key}' 及其所有内容？")
                confirm_col1, confirm_col2 = st.columns(2)
                with confirm_col1:
                    if st.button("✅ 是，删除", key=f"confirm_del_exec_btn_{filename}_{section_key}", use_container_width=True):
                        logger.info(f"用户确认删除顶级键: 文件={filename}, 键={section_key}")
                        # 将待删除的键存储在session state中
                        st.session_state['key_to_delete'] = {'filename': filename, 'key': section_key}
                        logger.info(f"标记待删除的顶级键: {st.session_state['key_to_delete']}")
                        # 清除当前的确认状态
                        del st.session_state[confirm_state_key]
                        # 触发重新运行以处理删除
                        st.rerun() 
                with confirm_col2:
                    if st.button("❌ 否，取消", key=f"cancel_del_exec_btn_{filename}_{section_key}", use_container_width=True):
                        logger.info(f"用户取消删除顶级键: 文件={filename}, 键={section_key}")
                        # 清除删除标记和确认状态
                        if 'key_to_delete' in st.session_state and st.session_state['key_to_delete'] == {'filename': filename, 'key': section_key}:
                            del st.session_state['key_to_delete']
                        del st.session_state[confirm_state_key] 
                        st.rerun() # 取消时需要重新运行以隐藏确认对话框
            else:
                # 显示初始删除按钮 - 更改为更醒目的样式
                st.markdown("<div style='margin-top: 10px;'></div>", unsafe_allow_html=True)  # 增加间距
                delete_btn_container = st.container()
                delete_btn_container.markdown("<div style='text-align: center;'></div>", unsafe_allow_html=True)
                
                # 使用更醒目的样式
                if st.button("⚠️ 删除顶级键 ⚠️", 
                             key=delete_section_btn_key, 
                             help=f"删除顶级键 '{section_key}' 及其所有内容",
                             use_container_width=True,
                             type="primary"):  # 使用主要按钮样式使其更突出
                    logger.info(f"用户点击删除顶级键按钮: 文件={filename}, 键={section_key}")
                    # 设置确认状态
                    st.session_state[confirm_state_key] = True
                    # 清除可能存在的旧删除标记
                    if 'key_to_delete' in st.session_state:
                         del st.session_state['key_to_delete']
                    st.rerun() # 重新运行以显示确认对话框
                
                st.caption("点击上方按钮可删除此顶级键及其所有内容")  # 添加明确的提示


    # --- 移除此处的顶级键删除处理逻辑 --- 
    # (这部分逻辑将移到manage_file_content函数的开头)

def manage_file_content(manager: SecureConfigManager, selected_file: str):
    """管理选定配置文件的内容 (包括视图切换)"""
    if not selected_file:
        st.info("请先选择一个配置文件。")
        return

    encryptor = get_encryptor()
    if not encryptor:
        st.error("无法初始化加密服务，无法查看或编辑文件。请确保主密钥已设置。")
        return

    # --- 在加载数据前处理待删除的顶级键 ---
    if 'key_to_delete' in st.session_state:
        delete_info = st.session_state['key_to_delete']
        # 确保删除操作是针对当前选定的文件
        if delete_info['filename'] == selected_file:
            logger.info(f"检测到待删除键: {delete_info['key']} in file {selected_file}")
            try:
                # 加载当前数据
                current_data = manager.get_decrypted_file_content(selected_file, encryptor)
                if current_data is not None and isinstance(current_data, dict):
                    key_to_remove = delete_info['key']
                    if key_to_remove in current_data:
                        logger.info(f"执行删除顶级键: {key_to_remove}")
                        del current_data[key_to_remove] # 直接从字典删除
                        # 保存修改后的数据
                        manager.encrypt_and_save_content(selected_file, current_data, encryptor)
                        st.success(f"成功删除顶级键: '{key_to_remove}'")
                        logger.info(f"成功删除并保存: {key_to_remove}")
                    else:
                        st.warning(f"尝试删除的键 '{key_to_remove}' 不存在。")
                        logger.warning(f"尝试删除的键 '{key_to_remove}' 在文件 {selected_file} 中不存在。")
                else:
                    st.error("无法加载或解密文件数据以执行删除操作。")
                    logger.error(f"无法加载或解密文件 {selected_file} 以执行删除操作。")
                
                # 无论成功与否，都清除删除标记
                del st.session_state['key_to_delete']
                # 再次重新运行以显示更新后的内容
                st.rerun() 
                
            except Exception as e:
                logger.error(f"处理删除顶级键 '{delete_info['key']}' 时出错: {e}", exc_info=True)
                st.error(f"删除顶级键时出错: {str(e)}")
                # 清除标记以避免循环错误
                if 'key_to_delete' in st.session_state:
                    del st.session_state['key_to_delete']
                # 可能需要再次rerun来显示错误后的状态
                st.rerun()
        # 如果标记的文件不是当前文件，暂时不处理（可能用户切换了文件）
        # 也可以选择在这里清除标记，取决于期望的行为

    # --- 正常显示文件内容 --- 
    st.subheader(f"📄 文件内容: {selected_file}{manager.CONFIG_EXTENSION}")

    # --- 视图模式切换 ---
    view_options = ["编辑文件", "查看密文"]
    view_mode_key = f"view_mode_{selected_file}"
    current_view_mode = st.session_state.get(view_mode_key, view_options[0])

    view_mode = st.radio(
        "查看模式",
        options=view_options,
        key=f"view_radio_{selected_file}",
        horizontal=True,
        index=view_options.index(current_view_mode)
    )
    if view_mode != current_view_mode:
        st.session_state[view_mode_key] = view_mode
        st.rerun()

    st.markdown("---")

    # --- 根据视图模式显示内容 ---
    active_view_mode = st.session_state.get(view_mode_key, view_options[0])

    if active_view_mode == "编辑文件":
        try:
            # 重新加载数据以防删除操作发生
            decrypted_data = manager.get_decrypted_file_content(selected_file, encryptor)
            
            if decrypted_data is None:
                # 处理无法解密的情况 (此逻辑应已在删除处理中考虑，但保留以防万一)
                if manager.get_config_data(selected_file) is not None:
                    st.error(f"无法解密文件 {selected_file}。可能是密钥错误或文件已损坏。")
                else:
                     st.error(f"找不到文件 {selected_file}。")
            else:
                # 增加顶级键的UI
                add_new_top_level_key(manager, selected_file, decrypted_data, encryptor)
                
                # 显示和编辑文件内容
                display_and_edit_file_content(manager, selected_file, decrypted_data, encryptor)
                
        except Exception as e:
            logger.error(f"处理文件 {selected_file} 时出错: {e}", exc_info=True)
            st.error(f"处理文件时出错: {str(e)}")
            
    else: # 密文视图
        try:
            raw_content = manager.get_encrypted_content(selected_file)
            if raw_content:
                st.code(raw_content, language="json")
            else:
                if manager.get_config_data(selected_file) is not None:
                    st.warning("文件存在但为空或无法读取。")
                else:
                    st.error("所选文件不存在。")
        except Exception as e:
            logger.error(f"读取加密内容时出错: {e}", exc_info=True)
            st.error(f"读取加密内容时出错: {e}")

def config_section_management():
    """Main UI for configuration file management."""
    st.subheader("📁 配置文件管理")
    
    # 添加使用说明
    with st.expander("ℹ️ 使用说明 (如何添加/删除顶级键和子键)", expanded=False):
        st.markdown("""
        ### 配置文件操作指南
        
        #### 文件操作
        - **选择文件**：从下拉菜单中选择要操作的配置文件
        - **删除文件**：点击"删除"按钮移除整个配置文件
        - **创建文件**：输入名称并点击"创建"按钮创建新的配置文件
        
        #### 顶级键操作
        - **添加顶级键**：在"添加顶级键"部分输入键名并点击"创建键"
        - **删除顶级键**：在每个顶级键展开器底部有"⚠️ 删除顶级键 ⚠️"按钮
        
        #### 子键操作
        - **添加子键**：在顶级键展开器内的"添加键值对"部分
        - **删除子键**：每个子键行右侧的"🗑️"按钮
        
        #### 视图模式
        - **编辑文件**：可以查看和编辑解密后的内容
        - **查看密文**：显示原始加密JSON内容，不可编辑
        """)

    # Initialize Config Manager if not already done
    if "config_manager" not in st.session_state or not st.session_state.config_manager:
        config_dir = SecureConfigManager.DEFAULT_CONFIG_DIR
        try:
            st.session_state.config_manager = SecureConfigManager(config_dir)
            logger.info(f"配置管理器已在 config_section_management 中初始化，使用目录: {config_dir}")
        except Exception as e:
            st.error(f"初始化配置管理器失败: {e}")
            logger.error(f"初始化 SecureConfigManager 失败: {e}", exc_info=True)
            return # Cannot proceed without manager

    manager: SecureConfigManager = st.session_state.config_manager

    # --- File Operations Section ---
    st.markdown("#### 文件操作")
    # Adjusted columns slightly, added small gap
    col_select, col_delete, col_create = st.columns([8, 1, 1], gap="small")

    selected_file = None # Default to None
    with col_select:
        st.markdown("###### 选择文件") # Added label
        existing_files = manager.list_configs()

        if not existing_files:
            st.caption("没有配置文件。")
            if 'selected_config_file' in st.session_state:
                del st.session_state['selected_config_file'] # Clear selection if no files exist
        else:
            default_index = 0
            current_selection = st.session_state.get('selected_config_file')
            if current_selection and current_selection in existing_files:
                try:
                    default_index = existing_files.index(current_selection)
                except ValueError:
                    st.session_state.selected_config_file = existing_files[0]
                    default_index = 0
            elif existing_files:
                 st.session_state.selected_config_file = existing_files[0]
                 default_index = 0

            selected_file = st.selectbox(
                "选择配置文件", # Label for screen readers, hidden visually
                existing_files,
                index=default_index,
                key="config_file_selector",
                label_visibility="collapsed"
            )
            if selected_file != st.session_state.get('selected_config_file'):
                 st.session_state.selected_config_file = selected_file
                 keys_to_clear = [k for k in st.session_state if k.startswith("confirm_delete_")]
                 for k in keys_to_clear:
                     del st.session_state[k]
                 st.rerun()

    selected_file_from_state = st.session_state.get('selected_config_file')

    with col_create:
        st.markdown("###### 创建文件") # Added label
        with st.popover("➕ 新建"):
            new_filename_key = "new_filename_input"
            new_filename = st.text_input("新文件名 (无需扩展名)", key=new_filename_key)
            if st.button("创建文件", key="create_file_button"):
                if not new_filename:
                    st.warning("请输入有效的文件名。")
                sanitized_filename = "".join(c if c.isalnum() or c in ('-', '_') else '_' for c in new_filename.strip())
                if not sanitized_filename:
                    st.warning("处理后的文件名无效。请使用字母、数字、- 或 _。")
                elif sanitized_filename in manager.list_configs():
                    st.warning(f"文件 '{sanitized_filename}{manager.CONFIG_EXTENSION}' 已存在。")
                else:
                    created = manager.create_config(sanitized_filename)
                    if created:
                        st.success(f"文件 '{sanitized_filename}{manager.CONFIG_EXTENSION}' 创建成功！")
                        st.session_state.selected_config_file = sanitized_filename
                        st.rerun()
                    else:
                        st.error("创建文件失败。")

    # --- Delete Selected File Button ---
    if selected_file_from_state:
        with col_delete:
            st.markdown("###### 删除文件") # Added label
            delete_file_btn_key = f"delete_file_btn_{selected_file_from_state}"
            # Removed the markdown spacer, use use_container_width
            if st.button("🗑️ 删除", key=delete_file_btn_key, help=f"删除文件 {selected_file_from_state}{manager.CONFIG_EXTENSION}", use_container_width=True):
                confirm_file_delete_key = f"confirm_delete_file_{selected_file_from_state}"
                st.session_state[confirm_file_delete_key] = not st.session_state.get(confirm_file_delete_key, False)
                st.rerun()

    # --- Delete Confirmation (appears below the main row if active) ---
    if selected_file_from_state:
        confirm_file_delete_key = f"confirm_delete_file_{selected_file_from_state}"
        if st.session_state.get(confirm_file_delete_key):
            # Indent confirmation slightly using columns or container
            with st.container(): # Use container for visual grouping
                st.warning(f"确认删除配置文件 '{selected_file_from_state}{manager.CONFIG_EXTENSION}'？此操作不可恢复！")
                confirm_col1, confirm_col2, _ = st.columns([1,1,4]) # Adjust columns for buttons
                with confirm_col1:
                    if st.button("✅ 是", key=f"confirm_delete_exec_{selected_file_from_state}", use_container_width=True):
                        deleted = manager.delete_config(selected_file_from_state)
                        del st.session_state[confirm_file_delete_key]
                        if deleted:
                            st.success(f"文件 '{selected_file_from_state}{manager.CONFIG_EXTENSION}' 已删除。")
                            del st.session_state['selected_config_file']
                            st.rerun()
                        else:
                            st.error("删除文件失败。")
                with confirm_col2:
                    if st.button("❌ 否", key=f"cancel_delete_exec_{selected_file_from_state}", use_container_width=True):
                        del st.session_state[confirm_file_delete_key]
                        st.rerun()

    st.markdown("---") # Separator before content management

    # --- File Content Management (Call Stub) ---
    if selected_file_from_state:
        manage_file_content(manager, selected_file_from_state)
    elif existing_files:
        st.info("请从上方选择一个配置文件。")
    # If no existing_files, the caption is shown in the selection column

def _render_s3_connection_test_button(params: Dict[str, Any]):
    """渲染S3连接测试按钮及其逻辑"""
    if st.button("测试连接", help="测试与S3服务的连接"):
        # 检查必要参数 bucket_name
        if not params.get("bucket_name"):
             st.error("❌ 请填写存储桶名称")
             return

        with st.spinner("正在测试连接..."):
            try:
                # 创建临时适配器
                test_adapter = S3StorageAdapter({})
                # 确保传递给 _create_s3_client 的都是有效参数
                client_params = {k: v for k, v in params.items() if v is not None and k in [
                    "endpoint_url", "aws_access_key_id", "aws_secret_access_key",
                    "region_name", "verify"
                ]}
                # 确保布尔型 "verify" 参数被正确传递
                client_params['verify'] = params.get('verify', True) 
                
                s3_client = test_adapter._create_s3_client(**client_params)

                # 尝试检查存储桶是否存在
                s3_client.head_bucket(Bucket=params["bucket_name"])
                st.success("✅ 连接测试成功！存储桶可访问")
            except Exception as e:
                st.error(f"❌ 连接测试失败: {str(e)}")

def _render_s3_params() -> Dict[str, Any]:
    """渲染并获取S3存储配置参数"""
    params = {}
    st.markdown("#### S3兼容存储配置")
    st.markdown("支持AWS S3, MinIO, 阿里云OSS等兼容S3协议的对象存储服务")

    # 必填参数 - 基本连接信息
    params["bucket_name"] = st.text_input("存储桶名称", help="S3存储桶或对象容器的名称")
    params["object_key"] = st.text_input("对象键名", "secure_config.json", help="存储配置的文件名或路径 (可能需要根据选定文件调整)") # Note: object_key might need dynamic adjustment

    col1, col2 = st.columns(2)
    with col1:
        service_type = st.radio(
            "选择S3服务类型",
            ["AWS S3", "兼容S3的服务"],
            key="s3_service_type_radio", # Add key for uniqueness
            help="选择AWS官方S3服务或其他兼容S3的服务"
        )

    if service_type == "兼容S3的服务":
        template_options = {t["name"]: k for k, t in S3_SERVICE_TEMPLATES.items()}
        selected_template_name = st.selectbox(
            "选择服务模板",
            list(template_options.keys()),
            key="s3_template_select", # Add key
            help="选择预设的服务提供商或自定义配置"
        )
        selected_template_key = template_options[selected_template_name]
        template = S3_SERVICE_TEMPLATES[selected_template_key]
        st.info(f"**{template['name']}**: {template['description']}")

        endpoint_url = st.text_input(
            "S3端点URL",
            value=template["endpoint_url"],
            key="s3_endpoint_input", # Add key
            help="S3兼容服务的完整URL地址，包含协议(http/https)和端口"
        )
        params["endpoint_url"] = endpoint_url if endpoint_url else None
        # 仅当端点也来自模板或自定义尚未设置区域时，才使用模板区域
        params["region_name"] = template["region_name"] if template["region_name"] and not params.get("region_name") else params.get("region_name")

    # 高级设置
    with st.expander("高级设置"):
        st.subheader("认证设置")
        col_ak, col_sk = st.columns(2)
        with col_ak:
            aws_access_key = st.text_input(
                "访问密钥ID",
                placeholder="S3访问密钥",
                key="s3_access_key_input", # Add key
                help="S3服务的访问密钥ID(Access Key ID)"
            )
            params["aws_access_key_id"] = aws_access_key if aws_access_key else None
        with col_sk:
            aws_secret_key = st.text_input(
                "秘密访问密钥",
                type="password",
                key="s3_secret_key_input", # Add key
                help="S3服务的秘密访问密钥(Secret Access Key)"
            )
            params["aws_secret_access_key"] = aws_secret_key if aws_secret_key else None

        st.subheader("区域和连接设置")
        col_region, col_ssl = st.columns(2)
        with col_region:
            # Get potential region from template or previous input
            default_region = params.get("region_name", "") 
            aws_region = st.text_input(
                "区域名称",
                value=default_region or "", # Ensure value is not None
                placeholder="例如: us-east-1",
                key="s3_region_input", # Add key
                help="S3服务的区域名称"
            )
            params["region_name"] = aws_region if aws_region else params.get("region_name") # Prioritize user input
        with col_ssl:
            verify_ssl = st.checkbox(
                "验证SSL证书",
                value=params.get("verify", True), # Persist state if exists
                key="s3_verify_ssl_checkbox", # Add key
                help="对于自签名证书可以关闭此选项"
            )
            params["verify"] = verify_ssl

        # 连接测试按钮
        _render_s3_connection_test_button(params)

    return params

def _render_webdav_connection_test_button(params: Dict[str, Any]):
    """渲染WebDAV连接测试按钮及其逻辑"""
    if st.button("测试连接", help="测试与WebDAV服务的连接"):
        with st.spinner("正在测试连接..."):
            try:
                required_params = ["webdav_url", "username", "password"]
                if not all(params.get(p) for p in required_params):
                    st.error("❌ 请填写所有必要参数（服务URL、用户名和密码）")
                    return

                # 创建临时适配器并进行测试
                test_adapter = WebDavStorageAdapter({})
                # Filter out None values before passing to client creation
                client_params = {k: v for k, v in params.items() if v is not None and k in [
                    "webdav_url", "username", "password", "verify_ssl", "timeout", "proxy"
                ]}
                 # Ensure boolean 'verify_ssl' param is passed correctly
                client_params['verify_ssl'] = params.get('verify_ssl', True)
                
                test_client = test_adapter._create_webdav_client(**client_params)

                # 发送PROPFIND请求检查服务是否可用
                session = test_client['session']
                base_url = test_client['base_url']
                timeout = test_client['timeout']
                response = session.request(
                    'PROPFIND',
                    base_url,
                    headers={'Depth': '0'},
                    timeout=timeout
                )
                response.raise_for_status()
                st.success("✅ 连接测试成功！WebDAV服务可访问")
            except Exception as e:
                st.error(f"❌ 连接测试失败: {str(e)}")

def _render_webdav_params() -> Dict[str, Any]:
    """渲染并获取WebDAV存储配置参数"""
    params = {}
    st.markdown("#### WebDAV服务配置")
    st.markdown("支持Nextcloud、ownCloud、Seafile等WebDAV协议服务")

    template_options = {t["name"]: k for k, t in WEBDAV_SERVICE_TEMPLATES.items()}
    selected_template_name = st.selectbox(
        "选择WebDAV服务类型",
        list(template_options.keys()),
        key="webdav_template_select", # Add key
        help="选择预设的WebDAV服务或自定义配置"
    )
    selected_template_key = template_options[selected_template_name]
    template = WEBDAV_SERVICE_TEMPLATES[selected_template_key]
    st.info(f"**{template['name']}**: {template['description']}")

    webdav_url = st.text_input(
        "WebDAV服务URL",
        value=template["webdav_url"],
        key="webdav_url_input", # Add key
        help="WebDAV服务的URL，例如：https://nextcloud.example.com/remote.php/dav/files/username/"
    )
    params["webdav_url"] = webdav_url if webdav_url else None

    file_path = st.text_input(
        "存储文件路径",
        value="configs/secure_config.json", # Note: May need dynamic adjustment based on selected file
        key="webdav_filepath_input", # Add key
        help="存储配置文件的路径，相对于WebDAV根目录"
    )
    params["file_path"] = file_path if file_path else None

    col_user, col_pass = st.columns(2)
    with col_user:
        username = st.text_input(
            "用户名",
            key="webdav_user_input", # Add key
            help="WebDAV服务的用户名"
        )
        params["username"] = username if username else None
    with col_pass:
        password = st.text_input(
            "密码",
            type="password",
            key="webdav_pass_input", # Add key
            help="WebDAV服务的密码"
        )
        params["password"] = password if password else None

    with st.expander("高级设置"):
        col_ssl, col_timeout = st.columns(2)
        with col_ssl:
            verify_ssl = st.checkbox(
                "验证SSL证书",
                value=params.get("verify_ssl", True), # Persist state
                key="webdav_verify_ssl_checkbox", # Add key
                help="对于自签名证书可以关闭此选项"
            )
            params["verify_ssl"] = verify_ssl
        with col_timeout:
            timeout = st.number_input(
                "连接超时(秒)",
                min_value=1,
                value=params.get("timeout", 30), # Persist state
                key="webdav_timeout_input", # Add key
                help="网络连接超时时间"
            )
            params["timeout"] = timeout

        proxy = st.text_input(
            "代理服务器",
            placeholder="例如：http://proxy.example.com:8080",
            key="webdav_proxy_input", # Add key
            help="HTTP/HTTPS代理服务器地址（可选）"
        )
        params["proxy"] = proxy if proxy else None

        # 连接测试按钮
        _render_webdav_connection_test_button(params)

    return params

def get_storage_parameters(adapter_type: str) -> Dict[str, Any]:
    """获取存储适配器参数"""
    if adapter_type == "s3":
        return _render_s3_params()
    else:  # webdav
        return _render_webdav_params()

def handle_export_operation(adapter_type: str, params: Dict[str, Any]):
    """处理配置导出操作"""
    encryptor = get_encryptor()
    if not encryptor:
        st.error("无法创建加密器，请检查主密钥设置。")
        return
    
    # 获取配置管理器
    if 'config_handler' not in st.session_state or not st.session_state.config_handler:
        st.error("配置管理器未初始化。")
        return
    
    config_manager = st.session_state.config_handler
    
    # 导出逻辑
    try:
        # 获取当前配置数据
        selected_file = st.session_state.get('selected_config_file')
        if not selected_file:
            st.error("请先选择要导出的配置文件。")
            return
        
        # 获取加密数据
        encrypted_data = config_manager.get_config_data(selected_file)
        if not encrypted_data:
            st.error(f"无法获取配置文件 {selected_file} 的数据。")
            return
        
        # 执行导出操作
        with st.spinner(f"正在导出到{STORAGE_TYPES[adapter_type]}..."):
            result = StorageOperations.handle_export(adapter_type, encrypted_data, **params)
        
        if result:
            st.success(f"已成功导出到{STORAGE_TYPES[adapter_type]}！")
        else:
            st.error(f"导出到{STORAGE_TYPES[adapter_type]}失败。")
            
    except Exception as e:
        st.error(f"导出操作失败: {str(e)}")

def handle_import_operation(adapter_type: str, params: Dict[str, Any]):
    """处理从存储服务导入配置的操作"""
    try:
        # 获取加密数据
        encrypted_data = StorageOperations.handle_import(adapter_type, **params)
        
        # 试图解密数据(检查是否可用)
        encryptor = get_encryptor()
        if not encryptor:
            st.error("无法创建加密器，请检查主密钥设置。")
            return
            
        # 显示导入的内容
        st.success("已成功从存储服务导入配置！")
        st.json(encrypted_data)
        
    except Exception as e:
        st.error(f"导入操作失败: {str(e)}")

def storage_operations():
    """数据存储操作模块 (Needs Update)"""
    st.subheader("☁️ 云端存储操作")
    
    # Ensure manager is available
    if 'config_manager' not in st.session_state or not st.session_state.config_manager:
        st.error("配置管理器未初始化。请先访问 '配置管理' 页面。")
        return
    manager: SecureConfigManager = st.session_state.config_manager

    # --- File Selection for Storage --- 
    available_files = manager.list_configs()
    if not available_files:
        st.warning("没有可用的配置文件进行云存储操作。请先在 '配置管理' 页面创建文件。")
        st.session_state.storage_target_file = None 
        return 

    default_storage_file_index = 0
    current_config_selection = st.session_state.get('selected_config_file')
    if current_config_selection and current_config_selection in available_files:
        try:
            default_storage_file_index = available_files.index(current_config_selection)
        except ValueError:
            pass 
            
    selected_storage_file = st.selectbox(
            "选择要导出/导入的配置文件",
            available_files,
            index=default_storage_file_index,
            key="storage_target_file_selector",
            help="选择将与云端存储交互的配置文件"
    )
    st.session_state.storage_target_file = selected_storage_file 
    # ---------------------------------
    
    st.markdown("#### 支持的存储服务...") # Simplified description
    
    operation_type = st.radio("选择操作类型", ["导出到云端", "从云端导入"], horizontal=True, key="storage_op_type")
    adapter_type = st.selectbox("选择存储类型", list(STORAGE_TYPES.keys()), format_func=lambda x: STORAGE_TYPES.get(x, x), key="storage_adapter_type")
    params = get_storage_parameters(adapter_type)
    
    required_params_filled = all(params.get(key) for key in get_required_params(adapter_type))
    button_disabled = not required_params_filled or not selected_storage_file
    
    if operation_type == "导出到云端":
        st.markdown(f"### 导出配置: {selected_storage_file}{manager.CONFIG_EXTENSION}")
        if st.button("执行导出操作", disabled=button_disabled):
            file_data = manager.get_config_data(selected_storage_file)
            if file_data is not None:
                handle_export_operation(adapter_type, params)
            else:
                st.error("无法读取文件内容导出。")
    else:  # Import Operation
        st.markdown(f"### 导入配置到: {selected_storage_file}{manager.CONFIG_EXTENSION}")
        st.warning("导入操作将覆盖所选文件的现有内容！")
        if st.button("执行导入操作", disabled=button_disabled):
            handle_import_operation(adapter_type, params) # Call the stubbed/updated function

def get_required_params(adapter_type: str) -> list:
    """获取指定存储适配器所需的必要参数列表"""
    adapters_params = {
        's3': ['bucket_name', 'object_key'],
        'webdav': ['webdav_url', 'username', 'password', 'file_path']
    }
    return adapters_params.get(adapter_type, [])

def get_navigation():
    """显示主导航并返回选中的选项卡"""
    st.sidebar.title("安全配置管理器")
    
    # 使用emoji显示选项卡
    selected = st.sidebar.radio(
        "导航",
        list(CONFIG_TABS.keys()),
        format_func=lambda x: f"{CONFIG_TABS[x]} {x}"
    )
    
    st.sidebar.divider()
    
    # 添加安全退出按钮
    if st.sidebar.button("🔒 安全退出", help="清除内存中的敏感数据并退出", use_container_width=True):
        secure_exit()
    
    # 侧边栏页脚
    st.sidebar.markdown("---")
    st.sidebar.caption("© 2025 安全配置管理器")
    
    return selected

def secure_exit():
    """安全退出程序，清理所有敏感数据"""
    st.info("正在安全清理内存数据...")
    
    try:
        # 清理会话状态中的敏感数据
        sensitive_fields = [
            'master_key', 'new_key', 'temp_key',
            'config_manager', 'kms_integration'
        ]
        
        # 逐个清除敏感字段
        for field in sensitive_fields:
            if field in st.session_state:
                if field in ['config_manager', 'kms_integration']:
                    # 对于复杂对象，使用secure_clear_object
                    SecureMemory.secure_clear_object(st.session_state[field])
                else:
                    # 对于简单数据类型，使用secure_erase
                    st.session_state[field] = SecureMemory.secure_erase(st.session_state[field])
        
        # 调用GC强制内存回收
        SecureMemory.force_gc()
        
        # 设置退出状态并清除会话状态
        st.session_state.clear()
        st.session_state.exiting = True
        
        # 显示退出消息
        st.success("内存已安全清理，请关闭浏览器窗口以完成退出")
        st.balloons()
        st.stop()
    except Exception as e:
        logger.error(f"安全退出失败: {str(e)}")
        st.error(f"安全退出时出现错误: {str(e)}")

def show_homepage():
    """显示首页内容"""
    st.title("🏠 欢迎使用 QuantHub安全配置管理器")

    st.markdown("""
    ## 系统功能介绍

    安全配置管理器是一个用于安全存储和管理配置数据的工具，具有以下特点：

    - **🔐 高级加密**: 使用AES-256算法加密所有敏感数据
    - **🔑 密钥管理**: 提供完整的密钥生成、轮换和管理功能
    - **⚙️ 灵活配置**: 支持管理多个独立的配置文件
    - **☁️ 云端存储**: 支持将配置导出到S3或WebDAV等云端存储
    - **🔐 KMS集成**: 支持与密钥管理服务(KMS)集成
    - **🛡️ 内存安全**: 提供安全内存管理，防止敏感数据泄露
    """) # 略微更新了描述

    st.info("👈 请使用左侧导航访问系统各功能模块")

    # 系统状态概览
    st.subheader("系统状态")
    col1, col2 = st.columns(2)

    with col1:
        # 通过SystemKeychain直接检查初始化状态
        is_keychain_initialized = SystemKeychain.is_initialized()
        if is_keychain_initialized:
            st.success("✅ 密钥系统已初始化")
        else:
            st.error("❌ 系统未初始化")
            if st.button("前往初始化", key="goto_init_home"):
                # 注意：用户需要通过侧边栏手动导航
                st.info("请在左侧导航栏选择 '安全密钥管理' 进行初始化。")

    with col2:
        # 检查配置管理器状态并计算文件数量
        if "config_manager" in st.session_state and st.session_state.config_manager:
            manager: SecureConfigManager = st.session_state.config_manager
            try:
                # 使用list_configs()获取文件数量
                config_files = manager.list_configs()
                file_count = len(config_files)
                if file_count > 0:
                    st.success(f"✅ 已找到 {file_count} 个配置文件")
                else:
                    st.info("ℹ️ 当前没有配置文件")
            except Exception as e:
                 logger.error(f"首页检查配置文件时出错: {e}", exc_info=True)
                 st.warning("⚠️ 检查配置文件时出错")
        elif is_keychain_initialized: # 仅当密钥链已初始化但管理器未初始化时显示警告（不应该经常发生）
            st.warning("⚠️ 配置管理器未初始化")
        # 如果密钥链也未初始化，则不需要显示消息


    # 安全功能说明
    with st.expander("🛡️ 安全功能说明", expanded=False):
        st.markdown("""
        ### 内存安全机制

        本系统实现了以下内存安全机制，确保敏感数据不会在内存中残留：

        1. **安全退出功能**: 在退出应用时，使用`SecureMemory`类安全清除所有敏感数据
        2. **密钥轮换清理**: 轮换密钥后，旧密钥会被安全擦除
        3. **分块内存管理**: 敏感数据和普通数据分开存储和处理

        ### 如何安全使用

        1. 使用完毕后，请点击侧边栏的"🔒 安全退出"按钮
        2. 定期轮换密钥以增强安全性
        3. 避免将配置或密钥保存在不安全的位置

        > 注意：即使使用安全退出，我们也建议在处理高敏感度数据后重启系统
        """)

def security_operations():
    """安全密钥管理操作"""
    st.title("🔑 安全密钥管理")
    
    # 检查系统初始化状态
    if not SystemKeychain.is_initialized():
        system_initialization()
    else:
        # 如果已初始化但会话状态未更新，则更新会话状态
        if not st.session_state.system_initialized:
            st.session_state.system_initialized = True
            # ... (初始化 config_manager, system_keychain, kms_integration - 不变) ...
            config_dir = SecureConfigManager.DEFAULT_CONFIG_DIR
            if "config_manager" not in st.session_state or not st.session_state.config_manager:
                try:
                    st.session_state.config_manager = SecureConfigManager(config_dir)
                    logger.info(f"配置管理器已在 security_operations 中初始化: {config_dir}")
                except Exception as e:
                    st.error(f"初始化配置管理器失败: {e}")
                    logger.error(f"在 security_operations 中初始化 SecureConfigManager 失败: {e}", exc_info=True)
            
            if "system_keychain" not in st.session_state or not st.session_state.system_keychain:
                st.session_state.system_keychain = SystemKeychain

            if "kms_integration" not in st.session_state or not st.session_state.kms_integration:
                kms_metadata_path = ".kms_metadata/kms_config.json"
                try:
                   st.session_state.kms_integration = KMSIntegration(
                       st.session_state.system_keychain, # Pass keychain instance
                       kms_metadata_path
                   )
                   logger.info("KMS 集成已在 security_operations 中初始化。")
                except Exception as e:
                    st.error(f"初始化 KMS 集成失败: {e}")
                    logger.error(f"初始化 KMS 集成失败: {e}", exc_info=True)


        # 显示高级密钥操作界面
        show_advanced_key_operations() # 这个函数现在会渲染加密UI

def configuration_operations():
    """配置管理操作"""
    st.title("⚙️ 配置管理")
    
    # Manager initialization is now handled within config_section_management
    # Ensure this function is called to trigger initialization if needed.
    config_section_management()

def main():
    """主函数"""
    st.set_page_config(
        page_title="安全配置管理器",
        page_icon="🔐",
        layout="wide"
    )
    
    # 初始化会话状态
    init_session_state()
    
    # 检查是否在退出状态
    if 'exiting' in st.session_state and st.session_state.exiting:
        st.success("已安全退出系统")
        st.info("为确保安全，请关闭此浏览器窗口")
        st.stop()
    
    # 配置页面
    selected_tab = get_navigation()
    
    # 系统初始化状态
    is_initialized = st.session_state.system_initialized
    
    # 根据选项卡显示不同内容
    if selected_tab == "首页":
        show_homepage() # 首页始终可以访问
    elif selected_tab == "安全密钥管理":
        security_operations() # 密钥管理始终可以访问
    elif selected_tab == "配置管理":
        if is_initialized:
            configuration_operations()
        else:
            st.warning("系统未初始化，请先完成安全密钥设置。")
            # 可以选择显示一个禁用的占位符或仅显示警告
    elif selected_tab == "云端存储":
        if is_initialized:
            storage_operations()
        else:
            st.warning("系统未初始化，请先完成安全密钥设置。")
    elif selected_tab == "KMS集成":
        if is_initialized:
            render_kms_integration_ui(
                st.session_state.kms_integration,
                st.session_state.system_keychain
            )
        else:
            st.warning("系统未初始化，请先完成安全密钥设置。")

if __name__ == "__main__":
    main()